package com.tanhua.dubbo.server.api;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.Users;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;


@Service(version = "1.0.0")
public class UsersApiImpl implements UsersApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存好友关系（双向添加）
     *
     * @param userId   ⽤户id
     * @param friendId 好友id
     * @return 好友关系主键id
     */
    @Override
    public String saveUsers(Long userId, Long friendId) {
        // 判断数据是否齐全
        if (!ObjectUtil.isAllNotEmpty(userId, friendId)) {
            return null;
        }

        // 校验用户与”好友“是否存在好友关系
        Criteria criteria = new Criteria();
        criteria.orOperator(
                Criteria.where("userId").is(userId)
                        .and("friendId").is(friendId),
                Criteria.where("userId").is(friendId)
                        .and("friendId").is(userId)
        );
        Query query = Query.query(criteria);
        long count = this.mongoTemplate.count(query, Users.class);
        if (count == 1) {
            // 双向绑定出错，需删除用户间的好友关系后重新注册好友关系
            Boolean bool = this.removeUsers(userId, friendId);
            if (bool) {
                // 删除成功，重新加好友
                this.saveUsers(userId, friendId);
            }
        } else if (count > 0) {
            // 表示存在好友关系
            return null;
        }

        Users users = null;
         long date = System.currentTimeMillis();
        // 保存用户与好友的关系
        users = new Users();
        users.setId(ObjectId.get());
        users.setUserId(userId);
        users.setFriendId(friendId);
         users.setDate(date);
        this.mongoTemplate.save(users);


        // 保存好友与用户的关系
        users = new Users();
        users.setId(ObjectId.get());
        users.setUserId(friendId);
        users.setFriendId(userId);
         users.setDate(date);
        this.mongoTemplate.save(users);

        return users.getId().toHexString();
    }

    /**
     * 删除好友数据（双向删除）
     *
     * @param userId   ⽤户id
     * @param friendId 好友id
     * @return 完成与否
     */
    @Override
    public Boolean removeUsers(Long userId, Long friendId) {
        // 判断数据是否齐全
        if (!ObjectUtil.isAllNotEmpty(userId, friendId)) {
            return false;
        }

        Query query = null;
        long count = 0;
        // 删除我与好友的关系数据
        query = Query.query(Criteria.where("userId").is(userId)
                .and("friendId").is(friendId));
        count += this.mongoTemplate.remove(query, Users.class).getDeletedCount();

        // 删除好友与我的关系数据
        query = Query.query(Criteria.where("userId").is(friendId)
                .and("friendId").is(userId));
        count += this.mongoTemplate.remove(query, Users.class).getDeletedCount();

        return count > 0 && count < 3;
    }


    /**
     * 根据⽤户id查询全部Users列表
     *
     * @param userId ⽤户id
     * @return 好友关系对象集合
     */
    @Override
    public List<Users> queryAllUsersList(Long userId) {
        Query query = Query.query(Criteria.where("userId").is(userId));
        return this.mongoTemplate.find(query, Users.class);
    }


    /**
     * 根据⽤户id查询Users列表
     * (分⻚查询)
     *
     * @param userId ⽤户id
     * @return 好友关系对象集合
     */
    @Override
    public PageInfo<Users> queryUsersList(Long userId, Integer page, Integer pageSize) {
        PageRequest pageable = PageRequest.of(page - 1, pageSize,
                Sort.by(Sort.Order.desc("created")));
        Query query = Query.query(Criteria.where("userId").is(userId))
                .with(pageable);
        List<Users> usersList = this.mongoTemplate.find(query, Users.class);

        PageInfo<Users> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(usersList);
        return pageInfo;
    }
}
